#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>

#include "data_type.h"
#include "alloc.h"
#include "memfunc.h"
#include "basefunc.h"
#include "struct_deal.h"
#include "crypto_func.h"
#include "memdb.h"
#include "message.h"
#include "ex_module.h"

#include "http_server.h"
extern struct timeval time_val={0,50*1000};

int http_comp_init(void * sub_proc,void * para)
{
	int ret;
	// add youself's plugin init func here
	return 0;
}

int http_comp_start(void * sub_proc,void * para)
{
	int ret;
	void * recv_msg;
	int i;
	int type;
	int subtype;


	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
				message_get_type(recv_msg),message_get_subtype(recv_msg));
			ex_module_sendmsg(sub_proc,recv_msg);
			continue;
		}
		if((type==TYPE(HTTP_SERVER))&&(subtype==SUBTYPE(HTTP_SERVER,ACTION)))
		{
			ret=proc_http_checkmsg(sub_proc,recv_msg);
		}
		else if((type==TYPE(HTTP_SERVER))&&(subtype==SUBTYPE(HTTP_SERVER,RESULT)))
		{
			ret=proc_http_checkdigest(sub_proc,recv_msg);
		}
		else
		{
			ex_module_sendmsg(sub_proc,recv_msg);
			//proc_echo_message(sub_proc,recv_msg);
		}
	}
	return 0;
}

int proc_http_checkmsg(void * sub_proc,void * recv_msg)
{
	int ret;	
	// get record from message
	RECORD(HTTP_SERVER,ACTION) * http_action;
	ret = message_get_record(recv_msg,&http_action,0);
	if(ret<0)
		return ret;
	if(http_action==NULL)
		return -EINVAL;
	// modify action parameter
	http_action->action = ENUM(HTTP_SERVER_ACTION,CHECK);

	void * new_msg;
	new_msg = message_create(TYPE_PAIR(HTTP_SERVER,ACTION),recv_msg);
	if(new_msg == NULL)
		return -EINVAL;
	ret = message_add_record(new_msg,http_action);
	if(ret<0)
		return ret;

	sleep(2);
	ret = ex_module_sendmsg(sub_proc,new_msg);

	return ret;
}

int proc_http_checkdigest(void * sub_proc,void * recv_msg)
{
	int ret;	
	// get record from message
	RECORD(HTTP_SERVER,RESULT) * http_result;
	ret = message_get_record(recv_msg,&http_result,0);
	if(ret<0)
		return ret;
	if(http_result==NULL)
		return -EINVAL;
	// get file client infomation 
	RECORD(HTTP_SERVER,SERVER) * http_server;
	DB_RECORD * db_record;
	db_record = memdb_find_byname(http_result->server_name,
			TYPE_PAIR(HTTP_SERVER,SERVER));
	if(db_record == NULL)
		return -EINVAL;
	http_server=db_record->record;	

	// calculate file's sm3 digest
	BYTE file_digest[DIGEST_SIZE];
	char file_name[DIGEST_SIZE*8];
	Strncpy(file_name,http_server->file_dir,DIGEST_SIZE*4);
	Strcat(file_name,"/");
	Strncat(file_name,http_result->file_name,DIGEST_SIZE*8);

	calculate_sm3(file_name,file_digest);

	if(Memcmp(file_digest,http_result->uuid,DIGEST_SIZE)==0)
	{
		http_result->result = ENUM(HTTP_SERVER_RESULT,SUCCEED);
	}
	else
	{
		http_result->result = ENUM(HTTP_SERVER_RESULT,ERR_NOTMATCH);
	}

	void * new_msg;
	new_msg = message_create(TYPE_PAIR(HTTP_SERVER,RESULT),recv_msg);
	if(new_msg == NULL)
		return -EINVAL;
	ret = message_add_record(new_msg,http_result);
	if(ret<0)
		return ret;

	ret = ex_module_sendmsg(sub_proc,new_msg);

	return ret;
}
